package com.jdcjk;

import android.app.Application;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.sqlite.SQLiteDatabase;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.support.v7.app.NotificationCompat;
import android.text.TextUtils;

import com.baidu.mapapi.SDKInitializer;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechUtility;
import com.jdcjk.chat.AppListener;
import com.jdcjk.chat.OpenFireChatManagerListener;
import com.jdcjk.chat.OpenFireChatMessageListener;
import com.jdcjk.chat.OpenFireConnectionListener;
import com.jdcjk.chat.OpenFireConnectionManager;
import com.jdcjk.chat.OpenFireRosterListener;
import com.jdcjk.chat.OpenFireRosterLoadedListener;
import com.jdcjk.project.car.view.CarActivity;
import com.jdcjk.project.main.model.entity.CarWarningInfo;
import com.jdcjk.util.L;
import com.jdcjk.util.PreferencesUtils;
import com.jdcjk.util.TerminalWarmingJudge;
import com.tencent.bugly.crashreport.CrashReport;
import com.tsz.afinal.FinalDb;
import com.zhy.http.okhttp.OkHttpUtils;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.jivesoftware.smack.chat.Chat;
import org.jivesoftware.smack.chat.ChatManager;
import org.jivesoftware.smack.roster.Roster;
import org.jivesoftware.smack.roster.RosterEntry;
import org.jivesoftware.smack.roster.RosterGroup;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;

/**
 * Created by dong on 2016/12/1.
 * 主服务
 */

public class MainApp extends Application {
    private static MainApp mainApp;
    // 监听器模式
    public static List<AppListener> appListeners = new ArrayList<>();

    private int notifId = 123;

    @Override
    public void onCreate() {
        super.onCreate();
        mainApp = this;
        // 初始化数据库
        getDb();
        initOkHttpClient();
        //初始化设置
        initSetting();
        //在使用SDK各组件之前初始化context信息，传入ApplicationContext
        //注意该方法要再setContentView方法之前实现
        SDKInitializer.initialize(getApplicationContext());
        //初始化EventBus
//        EventBus.getDefault().register(this);

        //初始化Log打印工具类
        L.init(this);

        // 获取当前包名
        String packageName = mainApp.getPackageName();
        // 获取当前进程名
        String processName = getProcessName(android.os.Process.myPid());
        // 设置是否为上报进程
        CrashReport.UserStrategy strategy = new CrashReport.UserStrategy(mainApp);
        strategy.setUploadProcess(processName == null || processName.equals(packageName));
        //初始化腾讯Bugly
        CrashReport.initCrashReport(getApplicationContext(), "ed7d03ed4d", true, strategy);
    }

    public void initSetting() {
        //默认推送，声音，震动都为关闭
        //如果已经存在设定值，则赋予设定值
        SharedPreferences sp = PreferencesUtils.getInstance(this);
        boolean pushInfo = sp.getBoolean(PreferencesUtils.PUSH_INFO_SWITCH, true);
        boolean vibraition = sp.getBoolean(PreferencesUtils.VIBRATION_SWITCH, true);
        boolean voice = sp.getBoolean(PreferencesUtils.VOICE_SWITCH, true);
        //默认为高德地图
        String mapType = sp.getString(PreferencesUtils.MAP_TYPE, "GaoDe");
        PreferencesUtils.setBoolean(this, PreferencesUtils.PUSH_INFO_SWITCH, pushInfo);
        PreferencesUtils.setBoolean(this, PreferencesUtils.VIBRATION_SWITCH, vibraition);
        PreferencesUtils.setBoolean(this, PreferencesUtils.VOICE_SWITCH, voice);
        PreferencesUtils.setString(this, PreferencesUtils.MAP_TYPE, mapType);

        //位置上报设置，默认上报时间间隔为5s，默认车牌号为""
        String reportTimeFrequency = sp.getString(PreferencesUtils.REPORT_TIME_FREQUENCY, "5");
        String licensePlateNumber = sp.getString(PreferencesUtils.LICENSE_PLATE_NUMBER, "");
        PreferencesUtils.setString(this, PreferencesUtils.REPORT_TIME_FREQUENCY, reportTimeFrequency);
        PreferencesUtils.setString(this, PreferencesUtils.LICENSE_PLATE_NUMBER, licensePlateNumber);

        //初始化科大讯飞语音合成
        SpeechUtility.createUtility(this, SpeechConstant.APPID + "=5899263d ");
    }

    public static MainApp getInstance() {
        return mainApp;
    }

    public void initOkHttpClient() {
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                // 连接超时时间
                .connectTimeout(10000L, TimeUnit.MILLISECONDS)
                // 加载超时时间
                .readTimeout(10000L, TimeUnit.MILLISECONDS)
                .build();
        OkHttpUtils.initClient(okHttpClient);
    }

    /**
     * ****************************************数据库相关****************************************
     */
    private static FinalDb db = null;

    public FinalDb getDb() {
        if (db == null) {
            db = FinalDb.create(this, "jdcjk.db", true, 1, dbUpdateListener);
        }
        return db;
    }

    public FinalDb.DbUpdateListener dbUpdateListener = new FinalDb.DbUpdateListener() {
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        }
    };
    /**
     * *************************************** 即时通信初始化 *************************************************
     */

    // XMPP连接
//    public static AbstractXMPPConnection xmppTcpConnection;
    // 监听器
    public static OpenFireConnectionListener openFireConnectionListener;
    public static OpenFireChatMessageListener chatMessageListener;
    public static OpenFireChatManagerListener chatManagerListener;
    public static OpenFireRosterListener rosterListener;
    public static OpenFireRosterLoadedListener rosterLoadedListener;
    // 聊天管理器
    public static ChatManager chatManager;
    // 会话
    public static Chat chat;
    //好友
    public static Roster roster;

    /**
     * 初始化即时通信连接
     */
    public synchronized void initXMPPTCPConnection() {
        // 连接OpenFire服务器
        OpenFireConnectionManager.getInstance().getXMPPTcpConnection();
        OpenFireConnectionManager.getInstance().connect();
        OpenFireConnectionManager.getInstance().setCallbackListener(new OpenFireConnectionManager.OnOpenFireConnectListener() {
            @Override
            public void onConnected() {
                String username = PreferencesUtils.getString(mainApp, Constant.UserInfo.account);
                String password = PreferencesUtils.getString(mainApp, Constant.UserInfo.passward);
//                String username = "18320699674";
//                String password = "123456";
                if (!TextUtils.isEmpty(username) && !TextUtils.isEmpty(password)) {
                    try {
                        OpenFireConnectionManager.getInstance().getXMPPTcpConnection().login(username, password, "jdcjk"); // 13631468075
                        initConnection();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }

    public synchronized void initConnection() throws Exception {
        if (isNetworkAvailable(MainApp.getInstance())) {
            if (OpenFireConnectionManager.getInstance().getXMPPTcpConnection() != null) {
                System.out.println("初始化聊天");
                openFireConnectionListener = new OpenFireConnectionListener();
                OpenFireConnectionManager.getInstance().getXMPPTcpConnection().addConnectionListener(openFireConnectionListener);
                // 获取会话管理器
                chatManager = ChatManager.getInstanceFor(OpenFireConnectionManager.getInstance().getXMPPTcpConnection());
                // 设置会话创建监听
                chatManagerListener = new OpenFireChatManagerListener();
                chatManager.addChatListener(chatManagerListener);
                // 创建一个会话
                chat = chatManager.createChat("service@" + OpenFireConnectionManager.getInstance().getXMPPTcpConnection().getServiceName());
                L.i("MainApp", "initConnection:chat " + "service@" + OpenFireConnectionManager.getInstance().getXMPPTcpConnection().getServiceName());
                // 获取好友管理器
                roster = Roster.getInstanceFor(OpenFireConnectionManager.getInstance().getXMPPTcpConnection());
                // 添加好友状态监听器
                rosterListener = new OpenFireRosterListener();
                roster.addRosterListener(rosterListener);
                // 获取好友在线状态
                rosterLoadedListener = new OpenFireRosterLoadedListener();
                roster.addRosterLoadedListener(rosterLoadedListener);
                getAllEntries(roster);
                getGroups(roster);
            }
        }
    }

    /**
     * 判断网络状况
     *
     * @param context
     * @return
     */
    public boolean isNetworkAvailable(Context context) {
        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connectivityManager == null) {
            return false;
        } else {
            // 获取NetworkInfo对象
            NetworkInfo[] networkInfos = connectivityManager.getAllNetworkInfo();
            if (networkInfos != null && networkInfos.length > 0) {
                for (int i = 0; i < networkInfos.length; i++) {
                    // 判断当前网络状态是否为连接状态
                    if (networkInfos[i].getState() == NetworkInfo.State.CONNECTED) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /**
     * 获取所有好友信息
     *
     * @param roster
     * @return
     */
    public static List<RosterEntry> getAllEntries(Roster roster) {
        List<RosterEntry> Entrieslist = new ArrayList<>();
        Collection<RosterEntry> rosterEntry = roster.getEntries();
        Iterator<RosterEntry> i = rosterEntry.iterator();
        while (i.hasNext()) {
            Entrieslist.add(i.next());
        }
        return Entrieslist;
    }

    /**
     * 获取所有组
     *
     * @param roster
     * @return 所有组集合
     */
    public static List<RosterGroup> getGroups(Roster roster) {
        List<RosterGroup> grouplist = new ArrayList<RosterGroup>();
        Collection<RosterGroup> rosterGroup = roster.getGroups();
        Iterator<RosterGroup> i = rosterGroup.iterator();
        while (i.hasNext()) {
            grouplist.add(i.next());
        }
        return grouplist;
    }

    /**
     * 接收收到的报警信息
     *
     * @param carWarningInfo 报警信息
     */
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void getWarningByEventBus(CarWarningInfo carWarningInfo) {
        //获得是否开启震动
        boolean isVibrate = PreferencesUtils.getBoolean(this, PreferencesUtils.VIBRATION_SWITCH);
        //获得是否开启声音
        boolean isVoice = PreferencesUtils.getBoolean(this, PreferencesUtils.VOICE_SWITCH);

        //通知栏显示报警信息
        NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
        //设置报警信息类型
        carWarningInfo.setWarningList(TerminalWarmingJudge.warmingJudge(carWarningInfo));

        mBuilder.setContentTitle(carWarningInfo.getDisplayid())//设置通知栏标题
                .setContentText(carWarningInfo.getWarningList().get(0)) //设置通知栏显示内容
                //  .setNumber(number) //设置通知集合的数量
                .setTicker(carWarningInfo.getWarningList().get(0)) //通知首次出现在通知栏，带上升动画效果的
                .setWhen(System.currentTimeMillis())//通知产生的时间，会在通知信息里显示，一般是系统获取到的时间
                .setPriority(Notification.PRIORITY_DEFAULT) //设置该通知优先级
                .setAutoCancel(true)//设置这个标志当用户单击面板就可以让通知将自动取消
                .setOngoing(false)//ture，设置他为一个正在进行的通知。他们通常是用来表示一个后台任务,用户积极参与(如播放音乐)或以某种方式正在等待,因此占用设备(如一个文件下载,同步操作,主动网络连接)
                .setSmallIcon(R.drawable.ic_launcher)//设置通知小ICON
                .setVibrate(isVibrate ? new long[]{0, 300, 500, 300} : new long[]{0, 0, 0, 0}) //设置震动方式，实现效果：延迟0ms，然后振动300ms，在延迟500ms，接着在振动300ms。
                .setDefaults(Notification.DEFAULT_SOUND);//添加默认声音提醒
        //跳转到MainActivity
        Intent resultIntent = new Intent(this, CarActivity.class);
        resultIntent.putExtra(Constant.TerminalInfo.terminalId, carWarningInfo.getId());
        resultIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        mBuilder.setContentIntent(pendingIntent);
        mNotificationManager.notify(notifId++, mBuilder.build());
    }

    /**
     * 获取进程号对应的进程名
     *
     * @param pid 进程号
     * @return 进程名
     */
    private static String getProcessName(int pid) {
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader("/proc/" + pid + "/cmdline"));
            String processName = reader.readLine();
            if (!TextUtils.isEmpty(processName)) {
                processName = processName.trim();
            }
            return processName;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        } finally {
            try {
                if (reader != null) {
                    reader.close();
                }
            } catch (IOException exception) {
                exception.printStackTrace();
            }
        }
        return null;
    }

}
